#pragma once
#include <iostream>
#include <string>
#include <vector>
#include "InetAddr.hpp"
#include "Log.hpp"

using namespace LogModule;

// 服务器只负责收消息，由路由功能来发送消息
class Route
{
private:
    // 判断用户是否存在
    bool IsExist(InetAddr &peer)
    {
        // 遍历一遍vector进行判断
        for (auto &user : _online_user)
        {
            if (user == peer) // 这里是InetAddr重载了operator==
            {
                return true;
            }
        }
        return false;
    }

    // 新增用户
    void AddUser(InetAddr &peer)
    {
        LOG(LogLevel::INFO) << "新增一个在线用户" << peer.StringAddr();
        _online_user.push_back(peer);
    }

    // 删除用户
    void DeleteUser(InetAddr &peer)
    {
        LOG(LogLevel::INFO) << "删除一个在线用户" << peer.StringAddr();
        auto it = _online_user.begin();
        while (it != _online_user.end())
        {
            if (*it == peer)
            {
                _online_user.erase(it);
                break;
            }
            it++;
        }
    }

public:
    Route() {}

    // 路由功能
    // 参数1：消息，参数2：谁发的消息
    void MessageRoute(int sockfd, const std::string &message, InetAddr &peer)
    {
        if (!IsExist(peer)) // 如果用户不存在
        {
            // 加入用户
            AddUser(peer);
        }

        // 我们直接在这里给message做一些处理，让大家知道是谁发的这条message
        // 比如：127.0.0.1:8080# 你好
        std::string send_message = peer.StringAddr() + "# " + message;

        // 遍历转发消息
        for (auto &user : _online_user)
        {
            sendto(sockfd, send_message.c_str(), send_message.size(), 0, (struct sockaddr *)(&user.NetAddr()), sizeof(user.NetAddr()));
        }

        // 如果这个用户想退出，我们目前没有啥好的解决方案，因为协议还没学
        // 所以我们用一个比较有bug的规定：当这个用户发QUIT时就代表这个用户想退出
        // 并且我们将退出逻辑放到发消息的下面就是为了该用户退出也可以提示其他用户
        // 让其他用户知道该用户退出了——也就是发了QUIT这一消息
        if (message == "QUIT")
        {
            // 那么我们就删除该用户
            DeleteUser(peer);
        }
    }

    ~Route()
    {
    }

private:
    // 首次给我发消息，等同于登录，将该用户存到容器中
    // 把所有的用户用vector容器管理起来
    std::vector<InetAddr> _online_user; // 在线用户
};